<template>
  <div ref="containerTableRef" class="common-table-wrap" style="background: #ffffff">
    <div v-if="isShowMenu" class="menu">
      <el-button v-if="menuConfig.isShowFull" text type="primary" @click="clickFullScreen">
        <vab-icon :icon="isFullscreen ? 'fullscreen-exit-fill' : 'fullscreen-fill'" />
      </el-button>
      <el-popover v-if="menuConfig.isShowSize" popper-class="custom-table-radio" trigger="hover">
        <el-radio-group v-model="lineHeight">
          <el-radio label="large">大</el-radio>
          <el-radio label="default">中</el-radio>
          <el-radio label="small">小</el-radio>
        </el-radio-group>
        <template #reference>
          <el-button text type="primary">
            <vab-icon icon="line-height" />
          </el-button>
        </template>
      </el-popover>
    </div>
    <el-table
      ref="tableRef"
      v-loading="isLoading"
      :border="border ?? true"
      :data="elTableData.datalist"
      :fit="fit ?? true"
      highlight-current-row
      :max-height="height"
      row-key="id"
      :show-summary="showSummary"
      :size="lineHeight"
      :stripe="stripe ?? true"
      @cell-click="handleCellClick"
      @row-click="handleRowClick"
      @row-dblclick="handleRowDBClick"
      @selection-change="handleSelectionChange"
      @sort-change="handleSorted"
    >
      <template v-for="item in columnList" :key="item.value">
        <el-table-column v-if="item.type === TableColumnOrFormTypeEnum.SELECTION" :fixed="item.fixed" type="selection" />
        <el-table-column v-if="item.type === TableColumnOrFormTypeEnum.INDEX" :fixed="item.fixed" label="序号" type="index" />
        <el-table-column
          v-if="item.type === TableColumnOrFormTypeEnum.DYNAMIC"
          align="center"
          :fixed="item.fixed"
          label="行操作"
          :type="operateDynamicTableRowType"
          width="135"
        >
          <template #default="scope">
            <el-button link size="small" type="primary" @click="onAddRow(scope.row)"> 添加 </el-button>
            <el-button link size="small" type="primary" @click="onDelRow(scope.row)"> 删除 </el-button>
          </template>
        </el-table-column>
        <el-table-column
          v-if="item.type === TableColumnOrFormTypeEnum.INPUT"
          :align="item.align || 'left'"
          :fixed="item.fixed"
          :label="item.label"
          :prop="item.value"
          :sortable="item.sortable || false"
          :width="item.width || '180'"
        >
          <template #default="scope">
            <el-input
              v-model="scope.row[item.value]"
              :disabled="scope.row[item.disableField] || item.disabled"
              :readonly="scope.row[item.readonlyField] || item.readonly"
            />
          </template>
        </el-table-column>
        <el-table-column
          v-if="item.type === TableColumnOrFormTypeEnum.SELECT"
          :align="item.align || 'left'"
          :fixed="item.fixed"
          :label="item.label"
          :prop="item.value"
          :sortable="item.sortable || false"
          :width="item.width || '180'"
        >
          <template #default="scope">
            <CommonSelect
              v-model="scope.row[item.value]"
              :disabled="scope.row[item.disableField] || item.disabled"
              :opition-list="getOptionLists(item.dictCode, item.dictUrl, item.value)"
              :placeholder="item.placeholder"
              :readonly="scope.row[item.readonlyField] || item.readonly"
            />
          </template>
        </el-table-column>
        <el-table-column
          v-if="item.type === TableColumnOrFormTypeEnum.SELECTTREE"
          :align="item.align || 'left'"
          :expand-level="item.expandLevel"
          :fixed="item.fixed"
          :label="item.label"
          :prop="item.value"
          :sortable="item.sortable || false"
          :width="item.width || '180'"
        >
          <template #default="scope">
            <CommonSelectTree
              v-model="scope.row[item.value]"
              :disabled="scope.row[item.disableField] || item.disabled"
              :multiple="item.multiple"
              :opition-list="getOptionLists(item.dictCode, item.dictUrl, item.value)"
              :placeholder="item.placeholder"
              :readonly="scope.row[item.readonlyField] || item.readonly"
            />
          </template>
        </el-table-column>
        <el-table-column
          v-if="item.type === TableColumnOrFormTypeEnum.RATE"
          :align="item.align || 'left'"
          :fixed="item.fixed"
          :label="item.label"
          :prop="item.value"
          :sortable="item.sortable || false"
          :width="item.width || '180'"
        >
          <template #default="scope">
            <el-rate v-model="scope.row[item.value]" :disabled="scope.row[item.disableField] || item.disabled" />
          </template>
        </el-table-column>
        <el-table-column
          v-if="item.type === TableColumnOrFormTypeEnum.DATE"
          :align="item.align || 'left'"
          :fixed="item.fixed"
          :label="item.label"
          :prop="item.value"
          :sortable="item.sortable || false"
          :width="item.width || '220'"
        >
          <template #default="scope">
            <el-date-picker
              v-model="scope.row[item.value]"
              :disabled="scope.row[item.disableField] || item.disabled"
              :format="item.dateFormat || 'YYYY-MM-DD'"
              :readonly="scope.row[item.readonlyField] || item.readonly"
              :type="item.dateType || 'date'"
              :value-format="item.dateValueFormate || 'YYYY-MM-DD'"
            />
          </template>
        </el-table-column>
        <el-table-column
          v-if="item.type === TableColumnOrFormTypeEnum.SWITCH"
          :align="item.align || 'left'"
          :fixed="item.fixed"
          :label="item.label"
          :prop="item.value"
          :sortable="item.sortable || false"
          :width="item.width || '80'"
        >
          <template #default="scope">
            <el-switch
              v-model="scope.row[item.value]"
              :active-value="item.activeValue"
              :disabled="scope.row[item.disableField] || item.disabled"
              :inactive-value="item.inactiveValue"
            />
          </template>
        </el-table-column>
        <el-table-column
          v-if="!item.type"
          :align="item.align || 'left'"
          :fixed="item.fixed"
          :label="item.label"
          :prop="item.value"
          :show-overflow-tooltip="item.overflow"
          :sortable="item.sortable || false"
          :width="item.width"
        />
      </template>
      <slot name="opreration"></slot>
      <template #empty>
        <span v-if="isShowEmptyText">暂无数据</span>
        <el-image v-else class="vab-data-empty" :src="getDataEmptyImg()" />
      </template>
    </el-table>
    <el-pagination
      v-if="isShowPagination && !isDynamic"
      background
      :current-page="tableQueryForm.pageNum"
      :layout="layout || defaultLayout"
      :page-size="tableQueryForm.pageSize"
      :total="total"
      @current-change="handleCurrentChange"
      @size-change="handleSizeChange"
    />
  </div>
</template>

<script setup>
import { doSorted, backTableHeight, getLocalStorage, postRequest, getDataEmptyImg } from "@/api/mains";
import Sortable from "sortablejs";
import { operateDynamicTableRowType } from "../type.constant";
import { TableColumnOrFormTypeEnum } from "@/plugins/commonType.enum.ts";
import CommonSelect from "@/plugins/form/components/CommonSelect.vue";
import CommonSelectTree from "@/plugins/form/components/CommonSelectTree.vue";
const $baseTableHeight = 1000; //inject("$baseTableHeight");
const props = defineProps({
  queryForm: {
    type: Object,
    default: () => {
      return {};
    }
  },
  modelValue: {
    type: Array,
    default: () => []
  },
  tableData: {
    type: Object,
    default: () => {
      return {};
    }
  }
});

const emit = defineEmits([
  "update:model-value",
  "update:query-form",
  "on-get-table-data",
  "on-handle-row-click",
  "on-handle-selection-change",
  "on-handle-db-row-click",
  "on-handle-cell-click"
]);

const {
  datalist,
  isShowPagination = ref(true),
  total,
  columnList,
  layout,
  maxHeight,
  isSelectRow,
  isShowEmptyText,
  menuConfig = ref({}),
  stripe,
  fit,
  border,
  showSummary,
  isLoading
} = toRefs(props.tableData);

const tableQueryForm = ref({ ...props.queryForm });

const isDynamic = computed(() => {
  const { columnList } = elTableData;
  return columnList.some(item => item.type === TableColumnOrFormTypeEnum.DYNAMIC);
});

const isShowMenu = computed(() => {
  const { isShowFull, isShowSize } = menuConfig.value || {};
  return isShowFull || isShowSize;
});
const elTableData = reactive({ ...props.tableData });
const tableRef = ref(null);
const { proxy } = getCurrentInstance();

const lineHeight = ref("default");
const defaultLayout = "total, sizes, prev, next, jumper";
const actualMaxHeight = (maxHeight && maxHeight.value) || backTableHeight() + 10;
const height = ref(actualMaxHeight);
const containerTableRef = ref();
const optionLists = reactive({});
const { toggle, isFullscreen } = useFullscreen(containerTableRef);
const getOptionLists = (code, url, key) => {
  if (optionLists[key]) {
    return optionLists[key];
  }
  optionLists[key] = [];
  if (code) {
    optionLists[key] = getLocalStorage()[code];
    return optionLists[key];
  } else if (url) {
    postRequest(url).then(res => {
      const { datas } = res;
      optionLists[key] = datas;
      return optionLists[key];
    });
  }
};
const clickFullScreen = () => {
  toggle().then(() => {
    handleHeight();
    tableRef.value.doLayout();
  });
};
const handleHeight = () => {
  if (isFullscreen.value) height.value = $baseTableHeight(1) + 200;
  else height.value = actualMaxHeight;
};
const setSort = () => {
  // 表格中需要实现行拖动，所以选中tr的父级元素

  const el = tableRef.value.$el.querySelector(".el-table__body-wrapper tbody"); // table

  Sortable.create(el, {
    ghostClass: "sortable-ghost",
    setData: function (dataTransfer) {
      dataTransfer.setData("Text", "");
    },
    onEnd: evt => {
      const { datalist } = elTableData;
      const targetRow = datalist.splice(evt.oldIndex, 1)[0]; // this.data是表格所有数据

      datalist.splice(evt.newIndex, 0, targetRow);
      elTableData.datalist = [...datalist];
      emit("update:model-value", elTableData.datalist);
    }
  });
};

/**
 * 新增表格行
 * @param {*} row 当前点击行数据
 */
const onAddRow = row => {
  const { datalist } = elTableData;
  const index = datalist.findIndex(item => item.id === row.id);
  if (~index) {
    // elTableData.datalist.push(elTableData.datalist[0])
    datalist.splice(index + 1, 0, {});
    elTableData.datalist = [...datalist];
    emit("update:model-value", elTableData.datalist);
  }
};

/**
 * 删除行
 * @param {*} row 当前点击行数据
 */
const onDelRow = row => {
  proxy.$baseConfirm("你确定要删除选中项吗", null, async () => {
    const { datalist } = elTableData;
    const index = datalist.findIndex(item => item.id === row.id);
    if (~index) {
      // elTableData.datalist.push(elTableData.datalist[0])
      datalist.splice(index, 1);
      elTableData.datalist = [...datalist];
      emit("update:model-value", elTableData.datalist);
    }
  });
};

const handleRowClick = row => {
  emit("on-handle-row-click", row);
};
const handleSorted = async val => {
  tableQueryForm.value = { ...props.queryForm };
  doSorted(val, tableQueryForm.value);
  console.warn("tableQueryForm.value", tableQueryForm.value);
  emit("update:query-form", tableQueryForm.value);
  emit("on-get-table-data");
};
const handleCurrentChange = val => {
  tableQueryForm.value = { ...props.queryForm };
  tableQueryForm.value.pageNum = val;
  emit("update:query-form", tableQueryForm.value);
  emit("on-get-table-data");
};
const handleSizeChange = val => {
  tableQueryForm.value = { ...props.queryForm };
  tableQueryForm.value.pageSize = val;
  emit("update:query-form", tableQueryForm.value);
  emit("on-get-table-data");
};

const handleSelectionChange = val => {
  emit("on-handle-selection-change", val);
};

const handleRowDBClick = (row, column) => {
  emit("on-handle-db-row-click", row, column);
};

const setCurrent = row => {
  tableRef.value.setCurrentRow(row);
};

const handleCellClick = (row, column, cell) => {
  emit("on-handle-cell-click", row, column, cell);
};

onMounted(() => {
  isDynamic.value && setSort();
});

watch(
  () => props.tableData,
  newVal => {
    elTableData.datalist = newVal.datalist;
  },
  {
    deep: true,
    immediate: true
  }
);

watch(
  () => datalist,
  newVal => {
    if (newVal && newVal.value.length > 0 && isSelectRow) {
      if (tableRef.value) {
        setCurrent(datalist.value[0]);
      }
    }
  },
  { deep: true, immediate: true }
);

defineExpose({});
</script>
<style scoped lang="scss">
.common-table-wrap {
  width: 100%;
  .menu {
    display: flex;
    align-items: center;
    :deep() {
      button {
        margin: 0 10px 10px 0;
      }
    }
  }
}
</style>
